package StudentControl.StudentManager;

import Domain.User;

import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;

public class LogIn {
    private ArrayList<User> userList;
//Constructor======================================================================
    public LogIn() {
    }

    public LogIn(ArrayList<User> userList) {
        this.userList = userList;
    }
//Getter and Setter==============================================================
    public ArrayList<User> getUserList() {
        return userList;
    }

    public void setUserList(ArrayList<User> userList) {
        this.userList = userList;
    }
//Method==========================================================================
    public void UserIn(ArrayList<User> userList){
        Scanner sc = new Scanner(System.in);
        loop1:while (true) {
        System.out.println("***************黑马管理系统登录界面***************");
        System.out.println("1.登录");
        System.out.println("2.注册");
        System.out.println("3.退出");
        System.out.println("请输入您的选择：");
        String choice = sc.nextLine();
        switch (choice) {
            case "1"://登录
                loop2:while (true) {
                    System.out.println("=====================");
                    System.out.println("请选择您的登录方式：");
                    System.out.println("1.账号密码登录");
                    System.out.println("2.手机号登录");
                    System.out.println("3.返回上一级");
                    System.out.println("请输入您的选择：");
                    String login = sc.nextLine();
                    switch (login) {
                        case "1"://账号登录
                            boolean flag = userLogin(userList);
                            if (flag) {
                                break loop1;
                            }
                            break;
                        case "2"://手机号登录
                            boolean flag2 = userLoginPhone(userList);
                            if (flag2) {
                                break loop1;
                            }
                            break;
                        case "3":
                            break loop2;
                        default:
                            System.out.println("您的输入有误");
                            break;
                    }
                }
                break;
            case "2"://注册
                loop3:while (true) {
                    System.out.println("=====================");
                    System.out.println("请选择您的注册方式：");
                    System.out.println("1.账号密码注册");
                    System.out.println("2.手机号注册");
                    System.out.println("3.返回上一级");
                    System.out.println("请输入您的选择：");
                    String register = sc.nextLine();
                    switch (register) {
                        case "1":
                            addUser(userList);
                            break;
                        case "2":
                            System.out.println("请输入您的手机号：");
                            String phoneNumber = sc.nextLine();
                            addUser(userList, phoneNumber);
                            break;
                        case "3":
                            break loop3;
                        default:
                            System.out.println("您的输入有误！");
                            break;
                    }
                }
                break;
            case "3":
                System.out.println("谢谢您的使用");
                System.exit(0);
            default:
                System.out.println("您的输入有误，请重新输入：");
                break;
            }
        }
    }
    //登陆界面用方法==========================================================================
    //用户登录----------------------------
    //手机号登录
    private static boolean userLoginPhone(ArrayList<User> userList) {
        /*
        根据用户输入的手机号以及验证码进行判断
        1.账号：需要位11位手机号，均为数字
                若非法，则返回登录界面
                若合法，但手机号未注册，则询问是否注册
                    是，调用手机号注册程序
                    否，返回登陆界面
        2.验证码：6位数验证码
                若输入错误则会要求再次输入
         */
        boolean flag = false;
        //1.接收用户输入的用户名以及密码
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入手机号：");
        String phoneNumber = sc.nextLine();
        //2.传入手机号当作用户名，检测是否位手机号
        StringBuilder sb = new StringBuilder(phoneNumber);
        if (sb.length() != 11) {
            //2.1若手机号不为11位，则返还错误信息。
            System.out.println("您输入手机号不为11位！");
            return flag;
        } else {
            //2.2检测手机号是否均为数字
            char[] chr = phoneNumber.toCharArray();
            for (int i = 0; i < chr.length; i++) {
                if (chr[i] < '0' || chr[i] > '9') {
                    System.out.println("您输入手机号包含非法字符！");
                    return flag;
                }
            }
        }
        //3.通过用户名在集合中找到用户对象,若没有则提示
        int index = getUserIndex(userList, phoneNumber);
        if (index == -1) {
            System.out.println("该用户名不存在，请问是否需要注册？【1】注册【2】退出");
            String num = sc.nextLine();
            switch (num) {
                case "1":
                    addUser(userList, phoneNumber);
                    return flag;
                case "2":
                    return flag;
                default:
                    System.out.println("您的输入有误！");
                    return flag;
            }
        }
        //4.基于验证码，比对验证码，一致则进入管理系统，不一致提示并退回界面
        String verCode = getCode(6);
        System.out.println("验证码：" + verCode);
        System.out.println("请输入验证码：");
        while (true) {
            String inCode = sc.next();
            if (verCode.equals(inCode)) {
                //5.打印信息
                System.out.println("登录成功，欢迎进入黑马学生管理系统！");
                break;
            } else {
                System.out.println("验证码输入错误，请重新输入：");
            }
        }
        flag = true;
        return flag;
    }

    //用户密码登录
    private static boolean userLogin(ArrayList<User> userList) {
        /*
        根据用户输入的8-11位用户名、8-16位密码以及4位验证码进行判断
        1.账号：8-11位用户名，判定是否合法，
                若不合法则提示并返回界面
                若没有用户名，则提示并返回登录界面
        2.密码：共三次输入机会
                若失败则重新输入，超过三次返回登录界面
        3.验证码：4位数验证码
                若输入错误则会要求再次输入
         */
        boolean flag = false;
        //1.接收用户输入的用户名以及密码
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < 3; i++) {
            System.out.println("请输入用户名【8-11位且为有大小写字母以及数字】：");
            String username = sc.next();
            StringBuilder sb = new StringBuilder(username);
            //1.1确认长度
            if (sb.length() < 8 || sb.length() > 11) {
                System.out.println("您输入的用户名长度不符");
                return flag;
            }
            //1.2是否有非法字符,只允许有数字、大写字母以及小写字母
            char[] chars = username.toCharArray();
            for (int i1 = 0; i1 < chars.length; i1++) {
                if (chars[i1] <= 47 || chars[i1] >= 123) {
                    System.out.println("包含非法字符");
                    return flag;
                } else if (chars[i1] <= 64 && chars[i1] >= 58) {
                    System.out.println("包含非法字符");
                    return flag;
                } else if (chars[i1] <= 96 && chars[i1] >= 91) {
                    System.out.println("包含非法字符");
                    return flag;
                }
            }

            //2.通过用户名在集合中找到用户对象,若没有则提示
            int index = getUserIndex(userList, username);
            if (index == -1) {
                System.out.println("该用户名不存在，请先注册后再登录！");
                return flag;
            }
            //3.比对密码是否一致，用户共有三次机会输入密码
            System.out.println("请输入密码：");
            String password = sc.next();
            User user = userList.get(index);
            if (password.equals(user.getPassword())) {
                break;
            } else {
                if (i == 2) {
                    System.out.println("您输入的密码不一致，此次登录机会已用完，请再想想吧~");
                    return flag;
                } else {
                    System.out.println("您输入的密码不一致，还有" + (2 - i) + "次机会");
                }
            }
        }
        //4.基于验证码，比对验证码，一致则进入管理系统，不一致提示并重新输入
        String verCode = getCode(4);
        System.out.println("验证码：" + verCode);
        System.out.println("请输入验证码：");
        while (true) {
            String inCode = sc.next();
            if (verCode.equals(inCode)) {
                //5.打印信息
                System.out.println("登录成功，欢迎进入黑马学生管理系统！");
                flag = true;
                break;
            } else {
                System.out.println("验证码输入错误，请重新输入：");
            }
        }
        return flag;
    }

    //注册用户----------------------------
    //手机号注册
    private static void addUser(ArrayList<User> userList, String phoneNumber) {
        /*
        账号：传入的手机号即为账号，会进行一下三个步骤判断是否合法：
            1.位数
            2.是否均为数字
                若非法则返回登录界面
        密码：密码默认8个0
        验证码：6位数验证码
                若非法则要求继续输入
         */
        //1.传入手机号当作用户名，检测是否位手机号
        Scanner sc = new Scanner(System.in);
        StringBuilder sb = new StringBuilder(phoneNumber);
        if (sb.length() != 11) {
            //1.1若手机号不为11位，则返还错误信息。
            System.out.println("您输入手机号不为11位！");
            return;
        } else {
            //1.2检测手机号是否均为数字
            char[] chr = phoneNumber.toCharArray();
            for (int i = 0; i < chr.length; i++) {
                if (chr[i] < '0' || chr[i] > '9') {
                    System.out.println("您输入手机号包含非法字符！");
                    return;
                }
            }
        }

        //2.验证用户名是否存在
        int index = getUserIndex(userList, phoneNumber);
        if (index != -1) {
            System.out.println("该用户名已存在");
            return;
        }
        //3.确认验证码
        String verCode = getCode(6);
        System.out.println("验证码：" + verCode);
        System.out.println("请输入验证码：");
        while (true) {
            String inCode = sc.next();
            if (verCode.equals(inCode)) {
                /*4.创建用户对象并存入
                若验证码通过，则自动创建用户对象

                用户名位电话号码，密码默认8个0
                 */
                String password = "00000000";
                User user = new User(phoneNumber, password);
                userList.add(user);
                //5.提示注册成功
                System.out.println("注册成功！");
                break;
            } else {
                System.out.println("验证码输入错误，请重新输入：");
            }
        }
    }

    //账号密码注册
    private static void addUser(ArrayList<User> userList) {
        /*
        账号：长度8-11位，只包含大小写字母以及数字
                若输入账号长度不一致或包含非法字符则会提示并返回登录界面
        密码：长度8-16位，必须包含至少一个大写字母、小写字母以及数字
                不符合则会提示并要求重新输入
        验证码：4位
                若不符合则重新输入
         */
        //1.用户输入用户名(8~11位)，要确认是否已有用户名
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入要创建的用户名，长度8~11位，且为大小写字母或数字：");
        String username;
        while (true) {
            username = sc.next();
            StringBuilder sb = new StringBuilder(username);
            //1.1确认长度
            if (sb.length() < 8 || sb.length() > 11) {
                System.out.println("您输入的用户名长度不符");
                return;
            }
            //1.2是否有非法字符,只允许有数字、大写字母以及小写字母
            char[] chars = username.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                if (chars[i] <= 47 || chars[i] >= 123) {
                    System.out.println("包含非法字符");
                    return;
                } else if (chars[i] <= 64 && chars[i] >= 58) {
                    System.out.println("包含非法字符");
                    return;
                } else if (chars[i] <= 96 && chars[i] >= 91) {
                    System.out.println("包含非法字符");
                    return;
                }
            }

            //1.3比较是否有重名用户名
            int index = getUserIndex(userList, username);
            if (index == -1) {
                break;
            } else {
                System.out.println("该用户名已存在");
                return;
            }
        }
        //2.让用户输入密码，需要8-16位密码且有大小写字母以及数字
        System.out.println("请输入密码：");
        String password;
        loop2:
        while (true) {
            password = sc.next();
            StringBuilder sb = new StringBuilder(password);
            //1.1确认长度
            if (sb.length() < 8 || sb.length() > 17) {
                System.out.println("您输入的密码长度不符");
                continue loop2;
            }
            //1.2是否有非法字符,只允许有数字、大写字母以及小写字母
            char[] chars = password.toCharArray();
            for (int i = 0; i < chars.length; i++) {
                if (chars[i] <= 47 || chars[i] >= 123) {
                    System.out.println("非法字符，请您重新输入密码：");
                    continue loop2;
                } else if (chars[i] <= 64 && chars[i] >= 58) {
                    System.out.println("非法字符，请您重新输入密码：");
                    continue loop2;
                } else if (chars[i] <= 96 && chars[i] >= 91) {
                    System.out.println("非法字符，请您重新输入密码：");
                    continue loop2;
                }
            }

            //1.3比较密码安全性
            int bigCount = 0;
            int smallCount = 0;
            int numCount = 0;
            for (int i = 0; i < chars.length; i++) {
                if (chars[i] >= 'a' && chars[i] <= 'z') {
                    smallCount++;
                } else if (chars[i] >= 'A' && chars[i] <= 'Z') {
                    bigCount++;
                } else {
                    numCount++;
                }
            }
            if (bigCount == 0) {
                System.out.println("密码需要包含至少一个大写字母，请重新输入密码：");
                continue loop2;
            } else if (smallCount == 0) {
                System.out.println("密码需要包含至少一个小写字母，请重新输入密码：");
                continue loop2;
            } else if (numCount == 0) {
                System.out.println("密码需要包含至少一个数字，请重新输入密码：");
                continue loop2;
            } else {
                break loop2;
            }
        }

        //3.确认密码
        System.out.println("请确定您的密码：");
        while (true) {
            String rePassword = sc.next();
            if (rePassword.equals(password)) {
                break;
            } else {
                System.out.println("输入错误，请再输一次：");
            }
        }

        //4.确认验证码
        String verCode = getCode(4);
        System.out.println("验证码：" + verCode);
        System.out.println("请输入验证码：");
        while (true) {
            String inCode = sc.next();
            if (verCode.equals(inCode)) {
                //5.创建用户对象并存入
                User user = new User(username, password);
                userList.add(user);
                //6.提示注册成功
                System.out.println("注册成功！");
                break;
            } else {
                System.out.println("验证码输入错误，请重新输入：");
            }
        }
    }

    //其他功能----------------------------
    //获取用户index，比对输入用户名是否已存在集合中
    public static int getUserIndex(ArrayList<User> userList, String username) {
        int index = -1;
        for (int i = 0; i < userList.size(); i++) {
            User user = userList.get(i);
            if (username.equals(user.getUsername())) {
                index = i;
                break;
            }
        }
        return index;
    }

    //获得指定位数验证码，由至少一个小写字母以及数字组成，位置不定
    public static String getCode(int a) {
        Random ran = new Random();
        StringBuilder sb = new StringBuilder("");
        char chr[] = new char[a];
        int smallCount = 0;
        int numCount = 0;
        while (true) {
            for (int i = 0; i < a; i++) {
                int num;
                /*这个循环用来设定验证码在数字以及小写字母范围
                '9'在码表中为57，'a'在码表中为97
                 */
                while (true) {
                    num = ran.nextInt(75) + 48;
                    if (num <= 57) {
                        numCount++;
                        break;
                    } else if (num >= 97) {
                        smallCount++;
                        break;
                    }
                }
                chr[i] = (char) num;
            }
            //验证码需要包含至少一个字母以及数字
            if(numCount != 0 && smallCount != 0){
                break;
            }
        }

        //通过StringBuilder获得验证码字符串
        for (int i = 0; i < chr.length; i++) {
            sb.append(chr[i]);
        }
        return sb.toString();
    }

}
